//测试asm的功能
/**visit类的信息
  * param	            参数	            示例	                                        解释
    int version	        版本号	        V1_5	                                    1.5版本
    int access	        访问标志	        ACC_PUBLIC + ACC_ABSTRACT + ACC_INTERFACE	公有抽象接口类
    String name	        类的全限定名称	“pkg/Comparable”	                        Comparable类名
    String signature	泛型签名	        null
    String superName	父类	            “java/lang/Object”	                        父类是Object
    String[] interfaces	接口	            new String[] { “pkg/Mesurable” }	        实现该接口
*
* */

/**visitField成员变量的信息
 *
*     param	            参数	            示例	                                        解释
*     int access	    访问标志	        ACC_PUBLIC + ACC_FINAL + ACC_STATIC	        公有静态变量
*     String name	    类的全限定名称	    “pkg/Comparable”	                        Comparable变量名
*     String descriptor	变量类型	        I                                           int型的变量
*     String signature	泛型	            null	                                    没有使用泛型
*     Object value	    常量	            new Object	                                (疑似)必须是常量方法才可以使用
 * */

/**visitMethod方法的信息
 *
 *    param	            参数	            示例	                                        解释
 *    int access	    访问标志	        ACC_PUBLIC + ACC_ABSTRACT + ACC_INTERFACE	公有抽象接口方法
 *    String name	    类的全限定名称	    “pkg/Comparable”	                        Comparable方法名
 *    String descriptor 变量类型	        (Ljava/lang/Object;)I                       有一个object的参数，返回值为int
 *    String signature	泛型	            null	                                    没有使用泛型
 *    String[] value	方法抛出的异常	    null	                                    方法没有抛出异常
 * */
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.FieldVisitor;
import org.objectweb.asm.MethodVisitor;

import java.io.IOException;
import java.util.Arrays;

import static org.objectweb.asm.Opcodes.ASM4;

public class AsmReader extends ClassVisitor {

    public AsmReader(){
        //传进去一个int 262144;
        super(ASM4);
    }

    //version代表着java版本
    @Override
    public void visit(int version, int access, String className, String signature, String superName, String[] interfaces){
        System.out.println(version+"|"+access+"|"+className+"|"+signature+"|"+superName+"|"+ Arrays.toString(interfaces));
        System.out.println(className+" extends "+ superName+" {");
    }

    //访问到成员变量时触发事件；descriptor是成员的类型
    @Override
    public FieldVisitor visitField(int access, String name, String descriptor, String signature, Object value) {
        System.out.println(access+"|"+name+"|"+descriptor+"|"+signature+"|"+value);
        System.out.println("        "+name);
        return super.visitField(access, name, descriptor, signature, value);
    }

    //访问到方法时触发事件；descriptor是方法的返回值
    @Override
    public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) {
        System.out.println(access+"|"+name+"|"+descriptor+"|"+signature+"|"+exceptions);
        System.out.println("   "+name+"()");
        return super.visitMethod(access, name, descriptor, signature, exceptions);
    }
    //到达class文件尾部，访问结束
    @Override
    public void visitEnd(){
        System.out.println("}");
    }


    //重写方法现在回想不就是生命周期原理吗
    public static void main(String[] args) throws IOException {
        //new一个自己，因为自己继承了ClassVisitor，而ClassReader需要ClassVisitor作为参数
        AsmReader ca = new AsmReader();
//
        ClassReader cr = new ClassReader("Stutem");
////        开始解析,第二个参数为何为0不清楚
        cr.accept(ca,0);
//        reader("Stutem");

    }
//

    public static void reader(byte[] b) throws IOException {
        //new一个自己，因为自己继承了ClassVisitor，而ClassReader需要ClassVisitor作为参数
        AsmReader ca = new AsmReader();

        ClassReader cr = new ClassReader(b);
//        开始解析,第二个参数为何为0不清楚
        cr.accept(ca,0);


    }
}
